/*
 * @(#)RegistryObjects.java
 * Date 2013-04-08
 * Version 1.0
 * Author Jim Horner
 * Copyright (c)2012
 */


package us.hornerscorners.lamppost.registry.model;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import us.hornerscorners.lamppost.model.common.IPatientAware;
import us.hornerscorners.lamppost.model.common.IPersistableModel;

import us.hornerscorners.lamppost.model.document.Association;
import us.hornerscorners.lamppost.model.document.DocumentEntry;
import us.hornerscorners.lamppost.model.document.Folder;
import us.hornerscorners.lamppost.model.document.SubmissionSet;

import us.hornerscorners.lamppost.model.patient.PatientIdentity;


/**
 *
 * @author jim
 */
public class RegistryObjects {

    /** Field description */
    private final Map<String, Association> associations;

    /** Field description */
    private final Map<String, DocumentEntry> documentEntries;

    /** Field description */
    private final Map<String, Folder> folders;

    /** Field description */
    private PatientIdentity patientIdentity;

    /** Field description */
    private final Set<String> references;

    /** Field description */
    private final Map<String, SubmissionSet> submissionSets;

    /**
     * Constructs ...
     *
     */
    public RegistryObjects() {

        super();

        this.documentEntries = new HashMap<>();
        this.submissionSets = new HashMap<>();
        this.folders = new HashMap<>();
        this.associations = new HashMap<>();
        this.references = new HashSet<>();
    }

    /**
     * Method description
     *
     *
     * @param otherList
     */
    public void addAll(RegistryObjects otherList) {

        this.documentEntries.putAll(otherList.documentEntries);
        this.folders.putAll(otherList.folders);
        this.submissionSets.putAll(otherList.submissionSets);
        this.associations.putAll(otherList.associations);
        this.references.addAll(otherList.references);
    }

    /**
     * Method description
     *
     *
     * @param assocs
     */
    public void addAllAssociations(Collection<Association> assocs) {

        for (Association assoc : assocs) {

            this.associations.put(assoc.getEntryURN(), assoc);
        }
    }

    /**
     * Method description
     *
     *
     * @param docEntries
     */
    public void addAllDocumentEntries(Collection<DocumentEntry> docEntries) {

        for (DocumentEntry docEntry : docEntries) {

            this.documentEntries.put(docEntry.getEntryURN(), docEntry);
        }
    }

    /**
     * Method description
     *
     *
     * @param folders
     */
    public void addAllFolders(Collection<Folder> folders) {

        for (Folder folder : folders) {

            this.folders.put(folder.getEntryURN(), folder);
        }
    }

    /**
     * Method description
     *
     *
     * @param entryURNs
     */
    public void addAllReferences(Collection<String> entryURNs) {

        this.references.addAll(entryURNs);
    }

    /**
     * Method description
     *
     *
     * @param subSets
     */
    public void addAllSubmissionSets(Collection<SubmissionSet> subSets) {

        for (SubmissionSet subSet : subSets) {

            this.submissionSets.put(subSet.getEntryURN(), subSet);
        }
    }

    /**
     * Method description
     *
     *
     * @param assoc
     */
    public void addAssociation(Association assoc) {

        if (assoc != null) {

            this.associations.put(assoc.getEntryURN(), assoc);
        }
    }

    /**
     * Method description
     *
     *
     * @param docEntry
     */
    public void addDocumentEntry(DocumentEntry docEntry) {

        if (docEntry != null) {

            this.documentEntries.put(docEntry.getEntryURN(), docEntry);
        }
    }

    /**
     * Method description
     *
     *
     * @param folder
     */
    public void addFolder(Folder folder) {

        if (folder != null) {

            this.folders.put(folder.getEntryURN(), folder);
        }
    }

    /**
     * Method description
     *
     *
     * @param entryURN
     */
    public void addReference(String entryURN) {

        this.references.add(entryURN);
    }

    /**
     * Method description
     *
     *
     * @param subSet
     */
    public void addSubmissionSet(SubmissionSet subSet) {

        if (subSet != null) {

            this.submissionSets.put(subSet.getEntryURN(), subSet);
        }
    }

    /**
     * Method description
     *
     */
    public void clear() {

        this.associations.clear();
        this.documentEntries.clear();
        this.folders.clear();
        this.references.clear();
        this.submissionSets.clear();
    }

    /**
     * Method description
     *
     *
     * @param uuid
     *
     * @return
     */
    public Association findAssociation(String uuid) {

        return this.associations.get(uuid);
    }

    /**
     * Method description
     *
     *
     * @param uuid
     * @return
     */
    public DocumentEntry findDocumentEntry(String uuid) {

        return this.documentEntries.get(uuid);
    }

    /**
     * Method description
     *
     *
     * @param uuid
     * @return
     */
    public Folder findFolder(String uuid) {

        return this.folders.get(uuid);
    }

    /**
     * Method description
     *
     *
     * @param uuid
     * @return
     */
    public SubmissionSet findSubmissionSet(String uuid) {

        return this.submissionSets.get(uuid);
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public IPatientAware[] getAllPatientAwareables() {

        List<IPatientAware> result = new ArrayList<>();

        // write document metadata
        result.addAll(this.documentEntries.values());
        result.addAll(this.folders.values());
        result.addAll(this.submissionSets.values());

        return result.toArray(new IPatientAware[result.size()]);
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public IPersistableModel[] getAllPersistables() {

        List<IPersistableModel> result = new ArrayList<>();

        // write document metadata
        result.addAll(this.documentEntries.values());
        result.addAll(this.folders.values());
        result.addAll(this.submissionSets.values());

        return result.toArray(new IPersistableModel[result.size()]);
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public String[] getAssociationURNs() {

        Collection<String> result = this.associations.keySet();

        return result.toArray(new String[result.size()]);
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public Association[] getAssociations() {

        Collection<Association> result = this.associations.values();

        return result.toArray(new Association[result.size()]);
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public DocumentEntry[] getDocumentEntries() {

        Collection<DocumentEntry> result = this.documentEntries.values();

        return result.toArray(new DocumentEntry[result.size()]);
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public String[] getDocumentEntryURNs() {

        Collection<String> result = this.documentEntries.keySet();

        return result.toArray(new String[result.size()]);
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public String[] getFolderURNs() {

        Collection<String> result = this.folders.keySet();

        return result.toArray(new String[result.size()]);
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public Folder[] getFolders() {

        Collection<Folder> result = this.folders.values();

        return result.toArray(new Folder[result.size()]);
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public PatientIdentity getPatientIdentity() {
        return patientIdentity;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public String[] getSubmissionSetURNs() {

        Collection<String> result = this.submissionSets.keySet();

        return result.toArray(new String[result.size()]);
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public SubmissionSet[] getSubmissionSets() {

        Collection<SubmissionSet> result = this.submissionSets.values();

        return result.toArray(new SubmissionSet[result.size()]);
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public String[] getSubmittedAssociationURNs() {

        List<String> result = new ArrayList<>();

        for (SubmissionSet subSet : this.submissionSets.values()) {

            for (Association assoc : subSet.getSubmittedAssociations()) {

                result.add(assoc.getEntryURN());
            }
        }

        return result.toArray(new String[result.size()]);
    }

    /**
     * Method description
     *
     *
     * @param entryURN
     *
     * @return
     */
    public boolean isReference(String entryURN) {

        return this.references.contains(entryURN);
    }

    /**
     * Method description
     *
     *
     * @param patientIdentity
     */
    public void setPatientIdentity(PatientIdentity patientIdentity) {
        this.patientIdentity = patientIdentity;
    }
}
